package com.jmex.audio;

import java.util.logging.Logger;

import com.jme.math.FastMath;
import com.jmex.audio.AudioTrack.TrackType;
import com.jmex.audio.event.TrackStateListener;
import com.jmex.audio.util.AudioDebugging;


/**
 * Much like the EnvironmentalPool but with only one sound playing at a time, using crossfade for transitions
 * and keeping track of all players current location to avoid playing the start of the environment-tracks again
 * and again.
 * 
 * @author Emanuel Greisen <jme@emanuelgreisen.dk>
 */
public class SoundEnvironment
{
	final static Logger logger = Logger.getLogger(SoundEnvironment.class.getName());
	private float crossFadeTime;
	private float volume;	
	private AudioTrack current_track;
	private TrackStateListener pause_when_fade_complete_listener = new TrackStateListener()
	{
		public void trackFinishedFade(AudioTrack track)
		{
			logger.info("Track.trackFinishedFade("+AudioDebugging.printSoundFileName(track)+")");
			if(track.getVolume() == 0.0f)
			{
		        track.pause();
		        track.removeTrackStateListener(this);
			}
		}

		public void trackPaused(AudioTrack track)
		{
			logger.info("Track.paused():"+AudioDebugging.printSoundFileName(track));
		}

		public void trackPlayed(AudioTrack track)
		{
			logger.info("Track.played():"+AudioDebugging.printSoundFileName(track));
		}

		public void trackStopped(AudioTrack track)
		{
			logger.info("Track.stopped():"+AudioDebugging.printSoundFileName(track));
		}
	};
	


	public SoundEnvironment(float crossFadeTime, float volume)
	{
		this.crossFadeTime = crossFadeTime;
		this.volume = volume;
	}
	
	public void setVolume(float volume)
	{
		this.volume = FastMath.clamp(volume, 0.0f, 1.0f);
		if(current_track != null)
		{
			current_track.fadeTo(0.2f, this.volume);
		}
	}

	/**
	 * Sets the current track for the environment.
	 * 
	 * @param track
	 */
	public void setCurrentTrack(AudioTrack track)
	{
		if(track == current_track)
			return; // We are already playing this track
		
		logger.info("setCurrentTrack("+AudioDebugging.printSoundFileName(current_track)+" -> "+AudioDebugging.printSoundFileName(track)+")");
		
		// Fade out old track
		if(current_track != null)
		{
			current_track.fadeTo(crossFadeTime, 0.0f);
		}
		
		current_track = track;
		
		// Fade in new track (and set some important stuff)
		if(current_track != null)
		{
			current_track.addTrackStateListener(pause_when_fade_complete_listener);
			current_track.setType(TrackType.ENVIRONMENT);
			current_track.setLooping(true);
			current_track.setEnabled(true);
			float crossFadeTimeActual = crossFadeTime;
			if(!current_track.isPlaying())
			{
				current_track.setVolume(0);
				crossFadeTimeActual *= 3;
			}
			current_track.fadeTo(crossFadeTimeActual, volume);
			if(!current_track.isPlaying())
			{
				current_track.play();
			}
		}
	}
}
